package pe.com.casadesign.dao.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
import org.springframework.stereotype.Repository;

import pe.com.casadesign.dao.PaisDAO;
import pe.com.casadesign.domain.Pais;
import pe.com.casadesign.domain.ListaPais;
import pe.com.casadesign.domain.Distrito;
import pe.com.casadesign.domain.ListaDistrito;

/**
 * Implementacion de PaisDAO.
 * 
 * @author Gustavo Susano
 * 
 */
@Repository
public class PaisDAOImpl implements PaisDAO {
	private static final Logger logger = LoggerFactory.getLogger(PaisDAOImpl.class);
	
	// Nombre Procedimientos Almacenados
	private static String SP_LISTAR_PAIS = "SP_LISTAR_PAIS";
	private static String SP_LISTAR_DISTRITO = "SP_LISTAR_DISTRITO";
		
	// Parametros de Salida
	private static String CODPAIS = "CODPAIS";
	private static String PAIS = "PAIS";
	
	private static String CODREGION = "CODREGION";
	private static String CODPROVINCIA = "CODPROVINCIA";
	private static String CODDISTRITO = "CODDISTRITO";
	private static String DESCRIPCION = "DESCRIPCION";
	private static String ESTADO = "ESTADO";
	
	private static String LISTADO = "LISTADO";
	
	private static String TOTAL_FILAS_AFECTADAS = "#update-count-1";
	
	private JdbcTemplate jdbcTemplate;

	@Autowired
    public void setDataSource(DataSource dataSource)
    {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }
	
	@Override
	public ListaPais listarPais() {
		logger.info("listarPais");

		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_LISTAR_PAIS).
	    						  returningResultSet(LISTADO, new RowMapper<Pais>(){
									@Override
									public Pais mapRow(final ResultSet rs, final int numRow) throws SQLException
								    {
								        final Pais pais = new Pais();
								        pais.setcodPais(rs.getInt(CODPAIS));
								        pais.setdesPais(rs.getString(PAIS).toString());
								        return pais;
								    }
	    						  }
								);

	    // Estableciendo parametros de entrada al SP
	    SqlParameterSource parametros = new MapSqlParameterSource(); 

	    // Establecer parametros y ejecutar SP
        Map<String,Object> data = llamarSP.execute(parametros);

        // Obteniendo lista generada de ejecutar SP
		@SuppressWarnings("unchecked")
		List<Pais> listaPais= (List<Pais>)data.get(LISTADO);
        
		// Instanciando objeto ListaPais
		ListaPais listaPaisResultado = new ListaPais();
        // Estableciendo resultado al objeto ListaPaisResultado
		listaPaisResultado.setLista(listaPais);
        
        if (logger.isDebugEnabled() && listaPaisResultado != null)
        {
            logger.debug("size=" + listaPaisResultado.size());
        }
        return listaPaisResultado;
	}
	
	@Override
	public ListaDistrito listarDistrito() {
		logger.info("listarDistrito");

		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_LISTAR_DISTRITO).
	    						  returningResultSet(LISTADO, new RowMapper<Distrito>(){
									@Override
									public Distrito mapRow(final ResultSet rs, final int numRow) throws SQLException
								    {
								        final Distrito distrito = new Distrito();
								        distrito.setCodigo(rs.getInt(CODDISTRITO));
								        distrito.setCodProvincia(rs.getInt(CODPROVINCIA));
								        distrito.setCodRegion(rs.getInt(CODREGION));
								        distrito.setDescripcion(rs.getString(DESCRIPCION));
								        distrito.setEstado(rs.getString(ESTADO));
								        return distrito;
								    }
	    						  }
								);

	    // Estableciendo parametros de entrada al SP
	    SqlParameterSource parametros = new MapSqlParameterSource(); 

	    // Establecer parametros y ejecutar SP
        Map<String,Object> data = llamarSP.execute(parametros);

        // Obteniendo lista generada de ejecutar SP
		@SuppressWarnings("unchecked")
		List<Distrito> listaDistrito= (List<Distrito>)data.get(LISTADO);
        
		// Instanciando objeto ListaDistrito
		ListaDistrito listaDistritoResultado = new ListaDistrito();
        // Estableciendo resultado al objeto ListaDistritoResultado
		listaDistritoResultado.setLista(listaDistrito);
        
        if (logger.isDebugEnabled() && listaDistritoResultado != null)
        {
            logger.debug("size=" + listaDistritoResultado.size());
        }
        return listaDistritoResultado;
	}
}